﻿namespace ImageProcessing.ImageProcessor
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// ColorSorting class
    /// </summary>
    public static class IMG_ColorSorting
    {
        /// <summary>
        /// Img_SortingType enum
        /// </summary>
        public enum Img_SortingType
        {
            /// <summary>
            /// min value
            /// </summary>
            Min,

            /// <summary>
            /// max value
            /// </summary>
            Max,

            /// <summary>
            /// median value
            /// </summary>
            Median,

            /// <summary>
            /// midpoint value
            /// </summary>
            Midpoint
        }

        /// <summary>
        /// Img_s the bit mix val.
        /// </summary>
        /// <param name="img_UnsortedImg">The img_ unsorted img.</param>
        /// <param name="type">The type.</param>
        /// <returns>the returned color</returns>
        public static Entities.Pixel Img_BitMixVal(Entities.IMG_Image img_UnsortedImg, Img_SortingType type)
        {
            try
            {
                Entities.Pixel returned_Pixel;
                Entities.Pixel returned_Pixel2;
                int img_SideLength = img_UnsortedImg.Width;
                ArrayList values = new ArrayList();                
                for (int i = 0; i < img_SideLength; i++)
                {
                    for (int j = 0; j < img_SideLength; j++)
                    {
                        if (img_UnsortedImg[i, j] == null)
                        {
                            continue;
                        }

                        values.Add(img_UnsortedImg[i, j].BitMixValue);
                    }
                }

                values.Sort();
                int returnValue = 0;
                int returnValue2 = 0;
                int[] convertR = new int[1];
                int[] convertG = new int[1];
                int[] convertB = new int[1];
                BitArray img_Red = new BitArray(8);
                BitArray img_Green = new BitArray(8);
                BitArray img_Blue = new BitArray(8);
                byte red = 0, green = 0, blue = 0;
                switch (type)
                {
                    case Img_SortingType.Min:
                        returnValue = (int)values[0];
                        break;
                    case Img_SortingType.Max:
                        returnValue = (int)values[values.Count - 1];
                        break;
                    case Img_SortingType.Median:
                        returnValue = (int)values[values.Count / 2];
                        break;
                    case Img_SortingType.Midpoint:
                        returnValue = (int)values[0];
                        returnValue2 = (int)values[values.Count - 1];

                        if ((returnValue % 2) == 1)
                        {
                            blue = (byte)(blue | byte.Parse("1"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            green = (byte)(green | byte.Parse("1"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            red = (byte)(red | byte.Parse("1"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            blue = (byte)(blue | byte.Parse("2"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            green = (byte)(green | byte.Parse("2"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            red = (byte)(red | byte.Parse("2"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            blue = (byte)(blue | byte.Parse("4"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            green = (byte)(green | byte.Parse("4"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            red = (byte)(red | byte.Parse("4"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            blue = (byte)(blue | byte.Parse("8"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            green = (byte)(green | byte.Parse("8"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            red = (byte)(red | byte.Parse("8"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            blue = (byte)(blue | byte.Parse("16"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            green = (byte)(green | byte.Parse("16"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            red = (byte)(red | byte.Parse("16"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            blue = (byte)(blue | byte.Parse("32"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            green = (byte)(green | byte.Parse("32"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            red = (byte)(red | byte.Parse("32"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            blue = (byte)(blue | byte.Parse("64"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            green = (byte)(green | byte.Parse("64"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            red = (byte)(red | byte.Parse("64"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            blue = (byte)(blue | byte.Parse("128"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            green = (byte)(green | byte.Parse("128"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            red = (byte)(red | byte.Parse("128"));
                        }

                        returned_Pixel = new Entities.Pixel(red, green, blue);

                        returnValue = (int)values[values.Count - 1];

                        red = 0;
                        green = 0;
                        blue = 0;
                        if ((returnValue % 2) == 1)
                        {
                            blue = (byte)(blue | byte.Parse("1"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            green = (byte)(green | byte.Parse("1"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            red = (byte)(red | byte.Parse("1"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            blue = (byte)(blue | byte.Parse("2"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            green = (byte)(green | byte.Parse("2"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            red = (byte)(red | byte.Parse("2"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            blue = (byte)(blue | byte.Parse("4"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            green = (byte)(green | byte.Parse("4"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            red = (byte)(red | byte.Parse("4"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            blue = (byte)(blue | byte.Parse("8"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            green = (byte)(green | byte.Parse("8"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            red = (byte)(red | byte.Parse("8"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            blue = (byte)(blue | byte.Parse("16"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            green = (byte)(green | byte.Parse("16"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            red = (byte)(red | byte.Parse("16"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            blue = (byte)(blue | byte.Parse("32"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            green = (byte)(green | byte.Parse("32"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            red = (byte)(red | byte.Parse("32"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            blue = (byte)(blue | byte.Parse("64"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            green = (byte)(green | byte.Parse("64"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            red = (byte)(red | byte.Parse("64"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            blue = (byte)(blue | byte.Parse("128"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            green = (byte)(green | byte.Parse("128"));
                        }

                        returnValue /= 2;
                        if ((returnValue % 2) == 1)
                        {
                            red = (byte)(red | byte.Parse("128"));
                        }

                        returned_Pixel2 = new Entities.Pixel(red, green, blue);
                        return new Entities.Pixel((returned_Pixel.Red + returned_Pixel2.Red) / 2, (returned_Pixel.Green + returned_Pixel2.Green) / 2, (returned_Pixel.Blue + returned_Pixel2.Blue) / 2);
                }

                red = 0;
                green = 0;
                blue = 0;
                if ((returnValue % 2) == 1)
                {
                    blue = (byte)(blue | byte.Parse("1"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    green = (byte)(green | byte.Parse("1"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    red = (byte)(red | byte.Parse("1"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    blue = (byte)(blue | byte.Parse("2"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    green = (byte)(green | byte.Parse("2"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    red = (byte)(red | byte.Parse("2"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    blue = (byte)(blue | byte.Parse("4"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    green = (byte)(green | byte.Parse("4"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    red = (byte)(red | byte.Parse("4"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    blue = (byte)(blue | byte.Parse("8"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    green = (byte)(green | byte.Parse("8"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    red = (byte)(red | byte.Parse("8"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    blue = (byte)(blue | byte.Parse("16"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    green = (byte)(green | byte.Parse("16"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    red = (byte)(red | byte.Parse("16"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    blue = (byte)(blue | byte.Parse("32"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    green = (byte)(green | byte.Parse("32"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    red = (byte)(red | byte.Parse("32"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    blue = (byte)(blue | byte.Parse("64"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    green = (byte)(green | byte.Parse("64"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    red = (byte)(red | byte.Parse("64"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    blue = (byte)(blue | byte.Parse("128"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    green = (byte)(green | byte.Parse("128"));
                }

                returnValue /= 2;
                if ((returnValue % 2) == 1)
                {
                    red = (byte)(red | byte.Parse("128"));
                }

                returnValue /= 2;
                returned_Pixel = new Entities.Pixel(red, green, blue);
                return returned_Pixel;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }
    }
}
